package cn.yangliu;

import cn.yangliu.comm.BaseComponent;
import cn.yangliu.comm.entity.JsonResult;
import cn.yangliu.comm.tools.IOUtils;
import cn.yangliu.comm.tools.ReflectUtils;
import cn.yangliu.comm.tools.SpringUtil;
import cn.yangliu.comm.tools.WebUtils;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Method;

/**
 * 作者 杨柳
 * 创建时间 2017-08-29 20:25
 */
@ControllerAdvice
public class WebExceptionAdvice extends BaseComponent {

    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ExceptionHandler(BindException.class)
    public Object handlebindException(BindException e, HttpServletRequest request, HttpServletResponse response) {
        BindingResult bindingResult = e.getBindingResult();
        String msg = bindingResult.getFieldError().getField()+"参数错误";
        if (bindingResult.hasErrors()) {
            String message = bindingResult.getFieldError().getDefaultMessage();
            if (message.length() < 100) {
                msg = bindingResult.getFieldError().getField()+message;
            }
        }

        if (WebUtils.checkJsonAjax()) {
            JsonResult result = new JsonResult("400", msg);
            printData(result, response);
            return null;
        } else {
            ModelAndView mav = new ModelAndView("error");
            request.setAttribute("msg", msg);
            return mav;
        }

    }

    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(Exception.class)
    public Object globalException(Exception e, HttpServletRequest request, HttpServletResponse response) {
        try{
            Class<?> authExClass = Class.forName("org.apache.shiro.authz.AuthorizationException");
            if (ReflectUtils.isSubClassOrEquesClass(e.getClass(),authExClass)){
                Class<?> adviceClass = Class.forName("cn.yangliu.shiro.AuthExceptionAdvice");
                Object advice = SpringUtil.getBean(adviceClass);
                Method method = adviceClass.getMethod("handleAuthorizationException",authExClass,HttpServletRequest.class,HttpServletResponse.class);
                return method.invoke(advice,e,request,response);
            }
        }catch (Exception t){

        }


        if (WebUtils.checkJsonAjax()) {
            JsonResult result = new JsonResult("500", "系统错误");
            printData(result, response);
            return null;
        } else {
            ModelAndView mav = new ModelAndView("error");
            request.setAttribute("msg", "系统错误");
            return mav;
        }

    }



    @ResponseStatus(HttpStatus.NOT_FOUND)
    public Object notFoudResource(HttpServletRequest request, HttpServletResponse response) {
        String msg = "您访问的资源不存在";
        if (WebUtils.checkJsonAjax()) {
            JsonResult result = new JsonResult("404", msg);
            printData(result, response);
            return null;
        } else {
            ModelAndView mav = new ModelAndView("404");
            request.setAttribute("msg", msg);
            return mav;
        }
    }

    protected void printData(Object data, HttpServletResponse response) {
        PrintWriter pw = null;
        try {
            pw = response.getWriter();
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            pw.println(data);
            pw.flush();
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage(),e);
        } finally {
            IOUtils.close(pw);
        }

    }
}
